<template>
  <div class="context">
    <div class="filter-container" style="display: flex; align-items: center; margin-bottom: 20px; flex-wrap: wrap">
      <!-- 表格头部按钮 -->
      <div style="display: flex; align-items: center; flex-wrap: wrap; line-height: 40px; width: 100%">
        <el-button v-if="mergedOptions.addRoute" type="primary" icon="Plus" @click="handleAdd">添加</el-button>
        <el-button v-if="mergedOptions.add?.enable" v-permission="[mergedOptions.add.permission]" type="primary" icon="Plus" @click="optAdd"
          >添加</el-button
        >
        <el-button
          v-if="mergedOptions.edit?.enable"
          v-permission="[mergedOptions.edit.permission]"
          :disabled="selectedIds.length === 0 || selectedIds.length > 1"
          type="warning"
          icon="Edit"
          @click="optEdit"
          >修改</el-button
        >
        <el-button
          v-if="mergedOptions.delete?.enable"
          v-permission="[mergedOptions.delete.permission]"
          :disabled="selectedIds.length === 0"
          type="danger"
          icon="Delete"
          @click="optDelete"
          >删除</el-button
        >
        <el-dropdown v-if="hasActions" style="margin-left: 10px" split-button @command="optAction">
          批量操作
          <template #dropdown>
            <el-dropdown-menu>
              <template v-for="(item, index) in mergedOptions.multiActions" :key="index">
                <el-dropdown-item v-permission="[item.permission]" :disabled="item.enable != null && !item.enable" :command="item">
                  {{ item.label }}
                </el-dropdown-item>
              </template>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        <div class="filter-content">
          <slot name="filter-content" />
        </div>
      </div>
    </div>
    <div style="display: flex; align-items: center; flex-wrap: wrap; margin-bottom: 10px">
      <slot name="tip-content" />
    </div>
    <el-table
      ref="tableRef"
      v-loading="listLoading"
      style="width: 100%"
      size="default"
      :data="dataList.records"
      :header-cell-class-name="'pg-header-cell'"
      :row-key="getRowKeys"
      :default-expand-all="false"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      :header-cell-style="{ background: '#f2f3f4', color: '#555', 'font-weight': 'bold', 'line-height': '40px' }"
      :expand-row-keys="expandKeys"
      border
      fit
      highlight-current-row
      @select="select"
      @select-all="selectAll"
      @expand-change="handleExpandChange"
    >
      <el-table-column
        v-if="mergedOptions.multi"
        :reserve-selection="false"
        :selectable="mergedOptions.selectable"
        align="center"
        type="selection"
        width="55"
      />
      <slot :data="dataList.records" name="data-columns" />
    </el-table>
    <pagination
      v-if="dataList.total > 0"
      :page="props.listQuery.pageNum"
      :limit="props.listQuery.pageSize"
      :total="dataList.total"
      @pagination="handlePagination"
    />
  </div>
</template>
<script setup lang="ts">
  defineOptions({ name: 'DataTable' })
  import { ref, reactive, computed, watch, nextTick, onMounted } from 'vue'
  import { useRouter } from 'vue-router'
  import { ElMessage, ElMessageBox, ElTable } from 'element-plus'
  // import checkPermission from '@/utils/permission'
  // import { postData } from '@/api/common'
  import { getFetch, postFetch, putFetch, deleteFetch } from '@/api/common'
  import { DataList, ListQuery, TableOptions } from '@/types/dataTable'
  import { debounce } from '@/utils/index'
  import { mergeConfig } from '@/utils/configMerge'
  import { flatListToTree } from '@/utils/flatListToTree'

  // Props
  interface Props {
    expand?: boolean
    options?: Partial<TableOptions>
    listQuery: ListQuery
    autoScroll?: boolean
    tree?: boolean
    done?: () => void
  }
  // 初始配置
  const defaultConfig = ref<TableOptions>({
    keyId: 'id',
    add: {
      enable: false, // 是否启用添加按钮
      permission: '', // 权限标识
      router: {}, // 路由配置
    },
    edit: {
      enable: false,
      permission: '',
      router: {},
    },
    delete: {
      enable: false,
      permission: '',
      url: '',
      tip: '确定要删除选中的数据吗？',
    },
    multiActions: [], // 批量操作
    listUrl: '', // 列表数据接口
    deleteUrl: '', // 删除数据接口
    stateUrl: '', // 状态修改接口
    multi: false, // 是否启用多选
    selectable: () => true,
  })
  //
  const props = withDefaults(defineProps<Props>(), {
    expand: false,
    autoScroll: true,
    options: () => ({}),
    listQuery: () => ({
      pageNum: 1,
      pageSize: 10,
      params: {},
    }),
    done: () => void 0,
    tree: false,
  })
  const mergedOptions = computed(() => {
    return mergeConfig(defaultConfig.value, props.options)
  })
  // Emits
  const emit = defineEmits<{
    'select-changed': [value: { ids: any[]; objs: any[] }]
    add: []
    edit: [id: any, row: any]
    delete: [ids: any[]]
    deleted: []
    'multi-actions': [value: { opt: string; ids: any[]; objs: any[] }]
    'update:listQuery': [value: ListQuery]
  }>()
  // Router
  const router = useRouter()
  // Refs
  const tableRef = ref<InstanceType<typeof ElTable>>()
  // Reactive data
  const expandKeys = ref<any[]>([])
  const dataList = ref<DataList>({
    total: 0,
    records: [],
  })
  const listLoading = ref(true)
  const selectedIds = ref<any[]>([])
  const selectedRows = ref<any[]>([])
  const multiShow = ref(false)
  // Computed
  const hasActions = computed(() => {
    if (!props.options.multiActions || props.options.multiActions.length === 0 || selectedIds.value.length === 0) {
      return false
    }
    // 校验批量操作权限
    for (let i = 0; i < props.options.multiActions.length; i++) {
      const action = props.options.multiActions[i]
      const permission = action.permission || ''
      // 未配置权限
      if (permission === '') {
        return true
      }
      // 有权限的
      // const pass = checkPermission([permission])
      const pass = true // 临时设置为true，等权限系统完善后再修改
      if (pass) {
        return true
      }
    }
    return false
  })

  // Watchers
  // 创建防抖的刷新函数
  const debouncedRefresh = debounce(
    () => {
      listLoading.value = true // 确保显示加载状态
      refresh()
    },
    800,
    false,
  )
  watch(
    () => JSON.stringify(props.listQuery.params),
    (newVal, oldVal) => {
      if (newVal !== oldVal) {
        listLoading.value = true // 立即显示加载状态
        debouncedRefresh()
      }
    },
  )
  watch(
    selectedRows,
    (val) => {
      selectedIds.value = val.map((item) => getRowKeys(item))
      emit('select-changed', { ids: selectedIds.value, objs: val })
    },
    { deep: true },
  )
  watch(
    () => props.expand,
    (val) => {
      toggleExpand()
    },
  )

  // Methods
  const getSelectedIds = () => {
    return selectedIds.value
  }
  // 处理展开/收起事件，实现手风琴效果
  const handleExpandChange = (row: any, expanded: boolean) => {
    const rowKey = getRowKeys(row)
    console.log('展开变化事件参数:', { row, expanded, rowKey })
    if (expanded) {
      // 行被展开了
      const currentExpandKeys = [...expandKeys.value]
      // 判断这是否是顶层行（没有父级的行）
      const isTopLevel = !findParentRow(row, dataList.value.records)
      if (isTopLevel) {
        // 顶层行：实现手风琴效果，只保留当前展开的顶层行及其所有子行
        const newExpandKeys = [rowKey]
        // 递归添加所有子行的key（如果子行之前是展开的）
        addChildrenKeys(row, newExpandKeys, currentExpandKeys)
        expandKeys.value = newExpandKeys
      } else {
        // 子行：直接添加到展开列表，不影响其他行
        if (!currentExpandKeys.includes(rowKey)) {
          expandKeys.value.push(rowKey)
        }
      }
    } else {
      // 行被收起了
      const keysToRemove = [rowKey]
      // 递归收起所有子行
      addChildrenKeysToRemove(row, keysToRemove)
      expandKeys.value = expandKeys.value.filter((key) => !keysToRemove.includes(key))
    }

    console.log('展开变化:', { rowKey, expanded, expandKeys: expandKeys.value })
  }

  // 查找父行
  const findParentRow = (targetRow: any, rows: any[]): any => {
    for (const row of rows) {
      if (row.children && row.children.length > 0) {
        const found = row.children.find((child: any) => getRowKeys(child) === getRowKeys(targetRow))
        if (found) {
          return row
        }
        // 递归查找
        const parentInChildren = findParentRow(targetRow, row.children)
        if (parentInChildren) {
          return parentInChildren
        }
      }
    }
    return null
  }

  // 递归添加子行的keys（只添加之前已经展开的）
  const addChildrenKeys = (row: any, newKeys: any[], oldKeys: any[]) => {
    if (row.children && row.children.length > 0) {
      for (const child of row.children) {
        const childKey = getRowKeys(child)
        // 只添加之前已经展开的子行
        if (oldKeys.includes(childKey)) {
          newKeys.push(childKey)
          addChildrenKeys(child, newKeys, oldKeys)
        }
      }
    }
  }

  // 递归添加要移除的子行keys
  const addChildrenKeysToRemove = (row: any, keysToRemove: any[]) => {
    if (row.children && row.children.length > 0) {
      for (const child of row.children) {
        const childKey = getRowKeys(child)
        keysToRemove.push(childKey)
        addChildrenKeysToRemove(child, keysToRemove)
      }
    }
  }

  const getRowKeys = (row: any) => {
    if (props.options.keyId) {
      return row[props.options.keyId]
    }
    return row['id']
  }
  /**新增操作按钮 */
  const optAdd = () => {
    // 路由跳转
    if (props.options.add?.router) {
      console.log('跳转到添加页面', props.options.add.router)
      router.push(props.options.add.router)
    }
    emit('add')
  }
  /**修改操作按钮 */
  const optEdit = () => {
    // 修改最后选定的项目
    const last = selectedRows.value[selectedRows.value.length - 1]
    const id = getRowKeys(last)

    // 跳转的
    if (props.options.edit?.router) {
      const routerConfig = props.options.edit.router
      const params = routerConfig.params
      const query = routerConfig.query
      if (params) {
        params.id = id
      }
      if (query) {
        query.id = id
      }
      router.push(routerConfig)
    }
    emit('edit', id, last)
  }
  /**删除按钮 */
  const optDelete = () => {
    if (props.options.delete?.url) {
      // 删除
      ElMessageBox.confirm(mergedOptions.value.delete.tip, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
        .then(() => {
          postFetch(props.options.delete!.url, { ids: selectedIds.value }, { noCache: true, clearCache: [props.options.listUrl] })
            .then((res) => {
              ElMessage.success('删除成功')
              emit('deleted')
            })
            .finally(() => {
              clearSelection()
              getList()
            })
        })
        .catch(() => {})
    } else {
      emit('delete', selectedIds.value)
    }
  }
  const optAction = (item: any) => {
    // 启用
    if (item.value === 'enable') {
      handleState(item.url, 0)
      return
    }
    // 禁用
    if (item.value === 'disable') {
      handleState(item.url, 1)
      return
    }
    // 改其他状态
    if (item.value === 'state') {
      handleState(item.url, item.state)
      return
    }
    // 向外回调的操作
    emit('multi-actions', { opt: item.value, ids: selectedIds.value, objs: selectedRows.value })
  }

  const handleState = (url: string, state: any) => {
    putFetch(url, { ids: selectedIds.value, state: state }).then((res) => {
      if (res.code === 0) {
        ElMessage.success('状态修改成功!')
        clearSelection()
        // 重新搜索
        getList()
      }
    })
  }

  const handleAdd = () => {
    if (props.options.addRoute) {
      router.push({ name: props.options.addRoute, params: {} })
      return
    }
    console.log('未设置添加数据跳转路由！')
  }

  /**统一请求参数 */
  const getList = (customQuery?: any) => {
    listLoading.value = true
    const queryParams = { ...(customQuery || props.listQuery) }
    // 只在需要强制刷新时添加时间戳
    if (customQuery?.forceRefresh) {
      queryParams.t = new Date().getTime()
    }
    postFetch(mergedOptions.value.listUrl, queryParams, {
      ttl: 5 * 60 * 1000, // 明确设置5分钟缓存
    })
      .then((response) => {
        console.log('获取列表数据:', response)
        if (props.tree) {
          const treeRecords = flatListToTree(response.records)
          dataList.value = {
            total: response.total,
            records: treeRecords,
          }
        } else {
          dataList.value = response
        }
        console.log('处理后的table数据', dataList.value.records)
        props.done?.()
        // 延迟回填选定状态
        nextTick(() => {
          toggleSelection()
          toggleExpand()
        })
      })
      .catch((error) => {
        console.error('获取列表数据失败:', error)
      })
      .finally(() => {
        listLoading.value = false // 确保在所有情况下都关闭加载状态
      })
  }

  const refresh = () => {
    console.log('refer刷新数据表格')
    listLoading.value = true // 确保显示加载状态
    clearSelection()
    const newQuery = {
      ...props.listQuery,
      pageNum: 1,
      params: { ...props.listQuery.params },
      forceRefresh: true, // 添加强制刷新标记
    }
    emit('update:listQuery', newQuery)
    nextTick(() => {
      getList(newQuery)
    })
  }
  const select = (selection: any[], row: any) => {
    const selected = selection.length && selection.indexOf(row) !== -1
    if (!selected) {
      let index = -1
      selectedRows.value.some((item, i) => {
        if (getRowKeys(item) == getRowKeys(row)) {
          index = i
          return true
        }
        return false
      })
      if (index > -1) selectedRows.value.splice(index, 1)
    } else {
      selectedRows.value.push(row)
    }
  }
  const selectAll = (selection: any[]) => {
    if (selection.length > 0) {
      // 全选
      dataList.value.records.forEach((item) => {
        if (!selectedRows.value.some((items) => getRowKeys(items) == getRowKeys(item))) {
          selectedRows.value.push(item)
        }
      })
    } else {
      // 全不选
      dataList.value.records.forEach((item) => {
        let index = -1
        selectedRows.value.some((items, i) => {
          if (getRowKeys(items) == getRowKeys(item)) {
            index = i
            return true
          }
          return false
        })
        if (index > -1) selectedRows.value.splice(index, 1)
      })
    }
  }

  const clearSelection = () => {
    tableRef.value?.clearSelection()
    selectedIds.value = []
    selectedRows.value = []
  }

  const toggleSelection = () => {
    if (!tableRef.value) {
      return
    }
    const ids = selectedRows.value.map((item) => getRowKeys(item))
    dataList.value.records.forEach((row) => {
      const selected = ids.some((ele) => ele === getRowKeys(row))
      tableRef.value?.toggleRowSelection(row, selected)
    })
  }

  const toggleExpand = () => {
    // 手风琴模式下，默认不展开任何行
    // 只有当 props.expand 为 true 时才展开所有行
    if (props.expand) {
      dataList.value.records.forEach((row) => {
        const key = getRowKeys(row)
        expandKeys.value.push(key)
      })
    } else {
      expandKeys.value = []
    }
  }

  const handlePagination = (payload: { page: number; limit: number }) => {
    console.log('触发了分页事件', payload)
    // 创建新的查询参数
    const newQuery = {
      ...props.listQuery,
      pageNum: payload.page,
      pageSize: payload.limit,
    }
    emit('update:listQuery', newQuery)
    // 直接使用新的查询参数获取数据，避免等待父组件更新
    getList(newQuery)
  }

  // 暴露给父组件的方法
  defineExpose({
    getSelectedIds,
    refresh,
    clearSelection,
    getList,
  })

  // 生命周期
  onMounted(() => {
    getList()
  })
</script>

<style scoped>
  .context {
    width: 100%;
    min-width: 0; /* 允许容器收缩到比内容更小 */
    max-width: 100%; /* 确保不会超出父容器 */
    box-sizing: border-box; /* 包含 padding 和 border 在宽度计算中 */
    overflow-x: auto; /* 内容过宽时显示横向滚动条 */
  }
  :deep(.filter-container .filter-item) {
    margin-left: 10px;
  }

  :deep(.filter-container .filter-item:first-child) {
    margin-left: 0;
  }

  :deep(.el-button--small) {
    padding: 9px;
  }
</style>
